package com.gzucm.Scholarship.controller;

import com.gzucm.Scholarship.annotation.AuthorityCheck;
import com.gzucm.Scholarship.common.enums.UserType;
import com.gzucm.Scholarship.dto.PasswordDTO;
import com.gzucm.Scholarship.dto.ResultDTO;
import com.gzucm.Scholarship.entity.UserInfo;
import com.gzucm.Scholarship.exception.ParameterException;
import com.gzucm.Scholarship.service.UserService;
import com.gzucm.Scholarship.util.OfficeUtil;
import com.gzucm.Scholarship.util.StringUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.Valid;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;
import java.util.Objects;

@Slf4j
@RestController
@Api(tags = "用户接口")
@RequestMapping("/api/user")
public class UserController {

    @Autowired
    private UserService userService;

    @PostMapping("/login")
    @ApiOperation(value = "用户登录", notes = "登录接口")
    public ResultDTO login(@RequestBody @Valid UserInfo userInfo) {
        return userService.login(userInfo);
    }

    @PostMapping("/logout")
    @ApiOperation(value = "用户退出", notes = "退出接口")
    public ResultDTO logout() {
        return userService.logout();
    }

    @AuthorityCheck(value = {UserType.ADMIN, UserType.TEACHER})
    @GetMapping("/findByType/{code}")
    @ApiOperation(value = "按身份查找用户", notes = "按身份查找用户")
    @ApiImplicitParam(name = "code", value = "用户类型Code", allowableValues = "-1,0,1,2", required = true, dataTypeClass = Integer.class)
    public ResultDTO findByType(@PathVariable("code") Integer code) {
        return userService.findByType(UserType.get(code));
    }

    @AuthorityCheck(value = {UserType.ADMIN, UserType.TEACHER})
    @GetMapping("/setCadres")
    @ApiOperation(value = "用id设置学生干部身份", notes = "设置学生干部身份")
    public ResultDTO setCadres(@RequestBody List<String> idList) {
        return userService.setCadres(idList);
    }

    @AuthorityCheck(value = {UserType.ADMIN, UserType.TEACHER})
    @PostMapping("/cancelCadres")
    @ApiOperation(value = "用id取消学生干部身份", notes = "取消学生干部身份")
    public ResultDTO cancelCadres(@RequestBody List<String> idList) {
        return userService.cancelCadres(idList);
    }

    @AuthorityCheck(value = {UserType.ADMIN, UserType.TEACHER})
    @DeleteMapping("/logicalDelete/{id}")
    @ApiOperation(value = "逻辑删除用户", notes = "逻辑删除用户")
    @ApiImplicitParam(name = "id", value = "用户id", required = true, dataTypeClass = String.class)
    public ResultDTO logicalDelete(@PathVariable("id") String id) {
        UserInfo info = userService.findById(id);
        if (Objects.isNull(info)) {
            return ResultDTO.failure(HttpStatus.BAD_REQUEST, "错误的id");
        }
        userService.logicalDelete(info);
        return ResultDTO.success("逻辑删除成功");
    }

    @AuthorityCheck(value = {UserType.ADMIN, UserType.TEACHER})
    @DeleteMapping("/logicalDelete")
    @ApiOperation(value = "逻辑删除用户组", notes = "逻辑删除用户组")
    @ApiImplicitParam(name = "year", value = "年级", required = true, dataTypeClass = Integer.class)
    public ResultDTO logicalDeleteByYear(@RequestParam("year") Integer year) {
        if (year < 1999 || year > 9999) {
            return ResultDTO.failure(HttpStatus.BAD_REQUEST, "入学年份不在[1999-9999]范围内,当前：" + year);
        }
        int count = userService.logicalDeleteByYear(year.toString());
        return ResultDTO.success("逻辑删除" + count + "位学生");
    }

    @GetMapping("/info")
    @ApiOperation(value = "用户信息", notes = "用户信息接口")
    @ApiImplicitParam(name = "id", value = "用户id", required = false, dataTypeClass = String.class)
    public ResultDTO getUserInfo(String id) {
        return userService.getUserInfo(id);
    }

    @PostMapping("/forgetPassword")
    @ApiOperation(value = "忘记密码", notes = "忘记密码接口")
    public ResultDTO forgetPassword(@RequestBody @Valid PasswordDTO dto) {
        if (StringUtils.isBlank(dto.getIdCard())) {
            throw new ParameterException("缺少身份凭证");
        }
        if (StringUtils.isBlank(dto.getNumber())) {
            throw new ParameterException("学号/工号 不能为空");
        }
        return userService.forgetPassword(dto);
    }

    @PostMapping("/resetPassword")
    @ApiOperation(value = "修改密码", notes = "修改密码接口")
    public ResultDTO resetPassword(@RequestBody @Valid PasswordDTO dto) {
        if (StringUtils.isBlank(dto.getOldPassword())) {
            throw new ParameterException("缺少旧密码");
        }
        return userService.resetPassword(dto);
    }

    @GetMapping("/findById/{id}")
    @ApiOperation(value = "用户登录", notes = "登录接口")
    @ApiImplicitParam(name = "id", value = "用户id", required = true, dataTypeClass = String.class)
    public ResultDTO findById(@PathVariable("id") String id) {
        UserInfo info = userService.findById(id);
        if (Objects.isNull(info)) {
            return ResultDTO.failure(HttpStatus.BAD_REQUEST, "错误的id");
        }
        return ResultDTO.success("获取成功", info);
    }

    @AuthorityCheck(value = {UserType.ADMIN, UserType.TEACHER})
    @PostMapping("/import")
    @ApiOperation(value = "导入用户", notes = "导入接口")
    public ResultDTO importUser(@ApiParam(value = "文件", required = true) MultipartFile file) {
        if (Objects.isNull(file) || file.isEmpty()) {
            return ResultDTO.failure(HttpStatus.BAD_REQUEST, "请上传文件");
        }
        String name = file.getOriginalFilename();
        if (!name.endsWith(".xls") && !name.endsWith(".xlsx")) {
            return ResultDTO.failure(HttpStatus.BAD_REQUEST, "请上传Excel文件");
        }
        Map<Integer, Map<Integer, Object>> map = OfficeUtil.readExcel(file);
        return userService.importUser(map);
    }

    @AuthorityCheck(value = {UserType.ADMIN, UserType.TEACHER})
    @GetMapping("/download/xlsx")
    @ApiOperation(value = "下载导入模板", notes = "模板下载接口")
    public ResponseEntity downloadXlsx() throws Exception {
        String fileName = URLEncoder.encode("导入模板.xlsx", "utf-8");
        HttpHeaders httpHeaders = new HttpHeaders();
        ContentDisposition contentDisposition =
                ContentDisposition.builder("attachment").filename(fileName).build();
        httpHeaders.setContentDisposition(contentDisposition);
        httpHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        InputStream in = this.getClass().getResourceAsStream("/static/导入模板.xlsx");
        byte[] body = new byte[in.available()];
        in.read(body);
        return new ResponseEntity(body, httpHeaders, HttpStatus.OK);
    }
}
